import numpy as np
import cv2
import dual_matrix_transform as dmt
import global_settings as R


# 将图片显示到形如photoshop棋盘的背景上，可显示透明图像
def imshow(title, im):
    """Decorator for OpenCV "imshow()" to handle images with transparency"""

    # Check we got np.uint8, 2-channel (grey + alpha) or 4-channel RGBA image
    if (im.dtype == np.uint8) and (len(im.shape) == 3) and (im.shape[2] in {2, 4}):

        # Pick up the alpha channel and delete from original
        alpha = im[..., -1] / 255.0
        im = np.delete(im, -1, -1)

        # Promote greyscale image to RGB to make coding simpler
        if len(im.shape) == 2:
            im = np.stack((im, im, im))

        h, w, _ = im.shape

        # Make a checkerboard background image same size, dark squares are grey(102), light squares are grey(152)
        f = lambda i, j: 102 + 50 * ((i + j) % 2)
        bg = np.fromfunction(np.vectorize(f), (16, 16)).astype(np.uint8)

        # Resize to square same length as longer side (so squares stay square), then trim
        if h > w:
            longer = h
        else:
            longer = w
        bg = cv2.resize(bg, (longer, longer), interpolation=cv2.INTER_NEAREST)
        # Trim to correct size
        bg = bg[:h, :w]

        # Blend, using result = alpha*overlay + (1-alpha)*background
        im = (alpha[..., None] * im + (1.0 - alpha[..., None]) * bg[..., None]).astype(np.uint8)

    cv2.imshow(title, im)


# 获取画布中心点
def get_center_point():
    return R.paintGroundSize[0] / 2, R.paintGroundSize[1] / 2


# 获取轴线矩阵
def get_axis_mat():
    zero_line = (
        (R.paintGroundSize[0] / 2, R.paintGroundSize[0] / 2 - R.axisCenterOffset),
        (R.paintGroundSize[0] / 2, 0))
    axis_mat = np.full((R.paintGroundSize[0], R.paintGroundSize[1], 4), 0, dtype="uint8")
    center_point = get_center_point()
    for i in range(R.axisNum):
        new_line = dmt.rotateLine(zero_line, np.pi / R.axisNum * i * 2, center_point)
        new_line = new_line.astype(int)
        cv2.line(
            axis_mat,
            new_line[0],
            new_line[1],
            color=R.axisColor,
            thickness=R.axisThickness
        )
    return axis_mat


# 获取空白矩阵
def get_blank_mat():
    return np.full((R.paintGroundSize[0], R.paintGroundSize[1], 4), R.bgColor, dtype="uint8")


# 合并图层
def merge_mat(mat1, mat2):
    mat1_clone = mat1.copy()
    rows, cols, channels = mat2.shape
    roi = mat1[0:rows, 0:cols]
    mat1gray = cv2.cvtColor(mat2, cv2.COLOR_BGR2GRAY)
    ret, mask = cv2.threshold(mat1gray, 1, 255, cv2.THRESH_BINARY)
    mask_inv = cv2.bitwise_not(mask)
    mat1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
    mat2_fg = cv2.bitwise_and(mat2, mat2, mask=mask)
    dst = cv2.add(mat1_bg, mat2_fg)
    mat1_clone[0:rows, 0:cols] = dst
    return mat1_clone


def hue2rgb(v1, v2, vh):
    if vh < 0:
        vh += 1
    if vh > 1:
        vh -= 1
    if 6 * vh < 1:
        return v1 + (v2 - v1) * 6 * vh
    if 2 * vh < 1:
        return v2
    if 3 * vh < 2:
        return v1 + (v2 - v1) * ((2 / 3) - vh) * 6
    return v1


# hsl转bgr颜色
def hsl2bgr(h, s, l):
    _r, _g, _b = 0, 0, 0
    var1, var2 = 0, 0
    if s == 0:
        _r = l * 255.
        _g = l * 255.
        _b = l * 255.
    else:
        if l < 0.5:
            var2 = l * (1 + s)
        else:
            var2 = (l + s) - (s * l)
        var1 = 2. * l - var2
    _r = 255. * hue2rgb(var1, var2, h + (1. / 3.))
    _g = 255. * hue2rgb(var1, var2, h)
    _b = 255. * hue2rgb(var1, var2, h - (1. / 3.))
    return _b, _g, _r
